#region "DataConfigurationService"

/*
 * ####     Developer Name : Wang Yucai
 * 
 * ####     Development Tool : Microsoft VisualStudio 2010 Ultimate Edition
 * 
 * ####     Create Time : 2014-07-15 16:21:19
 * 
 * ####     Namespace : Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.Configuration
 * 
 * ####     Type Name : DataConfigurationService
 * 
 * ####     Full Name : Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.Configuration.DataConfigurationService
 * 
 * ####     Machine Name : GLCHQWYCWINW7
 * 
 * ####     UserName : GUOCOLAND/wangyucai
 * 
 * ####     CLR Version : 4.0.30319.18444
 * 
 * ####     Target Framework Version : 4.0
 */

#endregion

using System;
using System.Configuration;
using System.Web;
using System.Web.Caching;
using Masterduner.SourceStudio.Practices.DevelopmentLibrary.Configuration;
using Masterduner.SourceStudio.Practices.DevelopmentLibrary.Runtime;
using Masterduner.SourceStudio.Practices.DevelopmentLibrary.Web.Configuration;

namespace Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.Configuration
{
    /// <summary>
    /// <para>Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.Configuration.DataConfigurationService</para>
    /// <para>
    /// Description
    /// </para>
    /// </summary>
    /// <remarks>
    /// <para>Target Framework Version : 4.0</para>
    /// </remarks>
    public class DataConfigurationService
    {
        #region ConfigurationSectionGroupName
        /// <summary>
        /// 数据库访问组件配置节组名称。
        /// </summary>
        public const string ConfigurationSectionGroupName = "developmentLibrary.dataConfiguration";
        #endregion
        private RunPlatformID _runPlatformID;
        private const string CacheServiceName = "DataApplicationBlockConfigurationCache";

        #region RunPlatformID
        /// <summary>
        /// 设置或获取当前应用的运行平台。
        /// </summary>
        protected virtual RunPlatformID RunPlatformID
        {
            get { return _runPlatformID; }
            set { _runPlatformID = value; }
        }
        #endregion

        #region Constructor

        /// <summary>
        /// <para>构造函数：</para>
        /// <para>初始化一个<see cref="DataConfigurationService" />对象实例。</para>
        /// </summary>
        /// <param name="runPlatform"><see cref="RunPlatformID"/>中的一个值。</param>
        public DataConfigurationService(RunPlatformID runPlatform)
        {
            this.RunPlatformID = runPlatform;
        }

        #endregion

        #region LoadFromCacheService
        /// <summary>
        /// 从缓存区中加载数据库访问组件配置。
        /// </summary>
        /// <returns><see cref="ConfigurationSectionGroup"/>对象实例。</returns>
        protected virtual ConfigurationSectionGroup LoadFromCacheService()
        {
            object configuration = null;
            if (this.RunPlatformID.Equals(RunPlatformID.AspNet))
            {
                configuration = HttpRuntime.Cache[CacheServiceName];
            }
            else
            {
                configuration = AppDomain.CurrentDomain.GetData(CacheServiceName);
            }
            return configuration.IsNull() ? null : configuration.ForceTo<ConfigurationSectionGroup>();
        }
        #endregion

        #region SaveInCacheService
        /// <summary>
        /// 将<paramref name="configuration"/>保存到缓存中。
        /// </summary>
        /// <param name="configuration"><see cref="ConfigurationSectionGroup"/>对象实例。</param>
        protected virtual void SaveInCacheService(ConfigurationSectionGroup configuration)
        {
            if (this.RunPlatformID.Equals(RunPlatformID.AspNet))
            {
                HttpRuntime.Cache.Insert(
                    CacheServiceName,
                    configuration,
                    new CacheDependency(GlobalWebConfigurationCacheDependency.GlobalCacheDependency.FullName),
                    Cache.NoAbsoluteExpiration,
                    new TimeSpan(0, 30, 0)
                    );
            }
            else
            {
                AppDomain.CurrentDomain.SetData(CacheServiceName, configuration);
            }
        }
        #endregion

        #region MergeDatabaseConnectionConfiguration
        /// <summary>
        /// 合并<see cref="DatabaseConnectionSection"/>配置。
        /// </summary>
        /// <param name="mainConfiguration">主要配置。</param>
        /// <param name="minorConfiguration">次要配置。</param>
        /// <returns></returns>
        protected virtual DatabaseConnectionSection MergeDatabaseConnectionConfiguration(
            DatabaseConnectionSection mainConfiguration,
            DatabaseConnectionSection minorConfiguration
            )
        {
            if (mainConfiguration.DatabaseConnections.IsNull() || mainConfiguration.DatabaseConnections.Count.Equals(0))
            {
                mainConfiguration = minorConfiguration;
            }
            else if (minorConfiguration.DatabaseConnections.NotIsNull() && minorConfiguration.DatabaseConnections.Count > 0)
            {
                bool exists = false;
                for (var iMinor = 0; iMinor < minorConfiguration.DatabaseConnections.Count; iMinor++)
                {
                    exists = false;
                    for (var iMain = 0; iMain < mainConfiguration.DatabaseConnections.Count; iMain++)
                    {
                        if (mainConfiguration.DatabaseConnections[iMain].Name.Equals(minorConfiguration.DatabaseConnections[iMinor].Name))
                        {
                            exists = true; break;
                        }
                    }
                    if (!exists) mainConfiguration.DatabaseConnections.Add(minorConfiguration.DatabaseConnections[iMinor]);
                }
            }
            return mainConfiguration;
        }

        /// <summary>
        /// 合并<see cref="DatabaseConnectionSection"/>配置。
        /// </summary>
        /// <param name="configurationInAppConfig">app.config或web.config中的配置。</param>
        /// <param name="configurationInDevLibConfig">开发库默认配置文件中的配置。</param>
        /// <param name="configurationInUserConfig">用户自定义配置文件中的配置。</param>
        /// <returns><see cref="DatabaseConnectionSection"/>对象实例。</returns>
        protected virtual DatabaseConnectionSection MergeDatabaseConnectionConfiguration(
            DatabaseConnectionSection configurationInAppConfig,
            DatabaseConnectionSection configurationInDevLibConfig,
            DatabaseConnectionSection configurationInUserConfig
            )
        {
            DatabaseConnectionSection mainConfiguration = null;
            if (configurationInUserConfig.NotIsNull())
            {
                mainConfiguration = configurationInUserConfig;
                if (configurationInAppConfig.NotIsNull()) mainConfiguration = MergeDatabaseConnectionConfiguration(mainConfiguration, configurationInAppConfig);
                if (configurationInDevLibConfig.NotIsNull()) mainConfiguration = MergeDatabaseConnectionConfiguration(mainConfiguration, configurationInDevLibConfig);
            }
            else if (configurationInAppConfig.NotIsNull())
            {
                mainConfiguration = configurationInAppConfig;
                if (configurationInDevLibConfig.NotIsNull()) mainConfiguration = MergeDatabaseConnectionConfiguration(mainConfiguration, configurationInDevLibConfig);
            }
            else if (configurationInDevLibConfig.NotIsNull()) mainConfiguration = configurationInDevLibConfig;
            return mainConfiguration;
        }
        #endregion

        #region MergeDatabaseProviderConfiguration
        /// <summary>
        /// 合并<see cref="DatabaseProviderSection"/>配置。
        /// </summary>
        /// <param name="mainConfiguration">主要配置。</param>
        /// <param name="minorConfiguration">次要配置。</param>
        /// <returns>合并后的<see cref="DatabaseProviderSection"/>对象实例。</returns>
        protected virtual DatabaseProviderSection MergeDatabaseProviderConfiguration(
            DatabaseProviderSection mainConfiguration,
            DatabaseProviderSection minorConfiguration
            )
        {
            if (mainConfiguration.DatabaseProviders.IsNull() || mainConfiguration.DatabaseProviders.Count.Equals(0))
            {
                mainConfiguration = minorConfiguration;
            }
            else if (minorConfiguration.DatabaseProviders.NotIsNull() && minorConfiguration.DatabaseProviders.Count > 0)
            {
                bool exists = false;
                for (var iMinor = 0; iMinor < minorConfiguration.DatabaseProviders.Count; iMinor++)
                {
                    exists = false;
                    for (var iMain = 0; iMain < mainConfiguration.DatabaseProviders.Count; iMain++)
                    {
                        if (mainConfiguration.DatabaseProviders[iMain].Name.Equals(minorConfiguration.DatabaseProviders[iMinor].Name))
                        {
                            exists = true; break;
                        }
                    }
                    if (!exists) mainConfiguration.DatabaseProviders.Add(minorConfiguration.DatabaseProviders[iMinor]);
                }
            }
            return mainConfiguration;
        }

        /// <summary>
        /// 合并<see cref="DatabaseProviderSection"/>配置。
        /// </summary>
        /// <param name="configurationInAppConfig">app.config或web.config中的配置。</param>
        /// <param name="configurationInDevLibConfig">开发库默认配置文件中的配置。</param>
        /// <param name="configurationInUserConfig">用户自定义配置文件中的配置。</param>
        /// <returns><see cref="DatabaseProviderSection"/>对象实例。</returns>
        protected virtual DatabaseProviderSection MergeDatabaseProviderConfiguration(
            DatabaseProviderSection configurationInAppConfig,
            DatabaseProviderSection configurationInDevLibConfig,
            DatabaseProviderSection configurationInUserConfig
            )
        {
            DatabaseProviderSection mainConfiguration = null;
            if (configurationInUserConfig.NotIsNull())
            {
                mainConfiguration = configurationInUserConfig;
                if (configurationInAppConfig.NotIsNull()) mainConfiguration = this.MergeDatabaseProviderConfiguration(mainConfiguration, configurationInAppConfig);
                if (configurationInDevLibConfig.NotIsNull()) mainConfiguration = this.MergeDatabaseProviderConfiguration(mainConfiguration, configurationInDevLibConfig);
            }
            else if (configurationInAppConfig.NotIsNull())
            {
                mainConfiguration = configurationInAppConfig;
                if (configurationInDevLibConfig.NotIsNull()) mainConfiguration = this.MergeDatabaseProviderConfiguration(mainConfiguration, configurationInDevLibConfig);
            }
            else if (configurationInDevLibConfig.NotIsNull()) mainConfiguration = configurationInDevLibConfig;
            return mainConfiguration;
        }
        #endregion

        #region GetConfiguration
        /// <summary>
        /// 获取数据库访问组件配置。
        /// </summary>
        /// <returns><see cref="ConfigurationSectionGroup"/>对象实例。</returns>
        public virtual ConfigurationSectionGroup GetConfiguration()
        {
            ConfigurationSectionGroup configuration = this.LoadFromCacheService();
            if (configuration.IsNull())
            {
                ConfigurationService configurationService = this.RunPlatformID.Equals(RunPlatformID.AspNet) ? new WebConfigurationService() : new ConfigurationService();
                ConfigurationSectionGroupResult<ConfigurationSectionGroup> result = configurationService.GetSectionGroup<ConfigurationSectionGroup>(ConfigurationSectionGroupName);
                DatabaseConnectionSection connectionSection = this.MergeDatabaseConnectionConfiguration(
                    result.ConfigurationSectionGroupInAppConfig.Sections[DatabaseConnectionSection.SectionName].ForceTo<DatabaseConnectionSection>(),
                    result.ConfigurationSectionGroupInDevLibConfig.Sections[DatabaseConnectionSection.SectionName].ForceTo<DatabaseConnectionSection>(),
                    result.ConfigurationSectionGroupInUserConfig.Sections[DatabaseConnectionSection.SectionName].ForceTo<DatabaseConnectionSection>()
                    );
                DatabaseProviderSection providerSection = this.MergeDatabaseProviderConfiguration(
                    result.ConfigurationSectionGroupInAppConfig.Sections[DatabaseProviderSection.SectionName].ForceTo<DatabaseProviderSection>(),
                    result.ConfigurationSectionGroupInDevLibConfig.Sections[DatabaseProviderSection.SectionName].ForceTo<DatabaseProviderSection>(),
                    result.ConfigurationSectionGroupInUserConfig.Sections[DatabaseProviderSection.SectionName].ForceTo<DatabaseProviderSection>()
                    );
                configuration = new ConfigurationSectionGroup();
                configuration.Sections.Add(DatabaseProviderSection.SectionName, providerSection);
                configuration.Sections.Add(DatabaseConnectionSection.SectionName, connectionSection);
                this.SaveInCacheService(configuration);
            }
            return configuration;
        }
        #endregion
    }
}

#region README

/*
 * ####     ©2014 Wang Yucai
 * 
 * ####     Contact me
 *                  
 *                  E-mail : Masterduner@Yeah.net
 *                  Mobile : 13621384677
 *                  QQ : 180261899
 */

#endregion